#include "KeyboardController.h"
#define BUFFER_SIZE		16

bool KeyboardController::initialize() {
	if FAILED( InputDevice::getDirectInput()->CreateDevice(GUID_SysKeyboard, &dKeyboard, NULL) ) {
		return false;
	} else {
		HRESULT hr;

		hr = dKeyboard->SetDataFormat( &c_dfDIKeyboard );
		if ( FAILED(hr) ) 
			return false;

		hr = dKeyboard->SetCooperativeLevel( InputController::getHWnd(), 
			DISCL_NONEXCLUSIVE  | DISCL_FOREGROUND);

		if ( FAILED(hr) ) 
			return false;


		// setup the buffer size for the mouse data
		DIPROPDWORD dipdw;

		dipdw.diph.dwSize = sizeof(DIPROPDWORD);
		dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
		dipdw.diph.dwObj = 0;
		dipdw.diph.dwHow = DIPH_DEVICE;
		dipdw.dwData = BUFFER_SIZE;

		hr = dKeyboard->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph );
		if ( FAILED(hr) ) 
			return false;

		return true;
	}


}
bool KeyboardController::terminate() {
	dKeyboard->Unacquire();
	return true;
}

void KeyboardController::unAcquire() {
	dKeyboard->Unacquire();
}

KeyboardController::MouseController() {
	dKeyboard=NULL;
}


void KeyboardController::acquire() {
	dKeyboard->Acquire();
}


HRESULT KeyboardController::poll() {

    DWORD i;

    if (NULL != dKeyboard) {
        DIDEVICEOBJECTDATA didod[ BUFFER_SIZE ];  // Receives buffered data 
        DWORD dwElements;
        HRESULT hr;
        hr = DIERR_INPUTLOST;

        while ( DI_OK != hr ) {

            dwElements = BUFFER_SIZE;
            hr = dKeyboard->GetDeviceData( sizeof(DIDEVICEOBJECTDATA),
                                            didod, 
                                            &dwElements, 
                                            0 );
            if (hr != DI_OK) {
                 // We got an error or we got DI_BUFFEROVERFLOW.
                 //
                 // Either way, it means that continuous contact with the
                 // device has been lost, either due to an external
                 // interruption, or because the buffer overflowed
                 // and some events were lost.
                 //
                 // Consequently, if a button was pressed at the time
                 // the buffer overflowed or the connection was broken,
                 // the corresponding "up" message might have been lost.
                 //
                 // But since our simple sample doesn't actually have
                 // any state associated with button up or down events,
                 // there is no state to reset.  (In a real game, ignoring
                 // the buffer overflow would result in the game thinking
                 // a key was held down when in fact it isn't; it's just
                 // that the "up" event got lost because the buffer
                 // overflowed.)
                 //
                 // If we want to be cleverer, we could do a
                 // GetDeviceState() and compare the current state
                 // against the state we think the device is in,
                 // and process all the states that are currently
                 // different from our private state.
                hr = dKeyboard->Acquire();
                if ( FAILED(hr) )  
                    return hr;

			} //Fin IF

		} //fin WHILE
			

        if ( FAILED(hr) )  
            return hr;

        // Study each of the buffer elements and process them.
        //
        // Since we really don't do anything, our "processing"
        // consists merely of squirting the name into our
        // local buffer.

		for (i = 0; i < dwElements; i++) {
            // this will display then scan code of the key
            // plus a 'D' - meaning the key was pressed 
            //   or a 'U' - meaning the key was released
            
            //          didod[ i ].dwOfs,

			if (didod[i].dwData & 0x80)
				keyDown(didod[i].dwOfs); // & 0x80) ? "D" : "U");
			else
				keyUp(didod[i].dwOfs); // & 0x80) ? "D" : "U");
        }


    return S_OK;
	} else {
		return -1;
	}
}
